// 颜色转化
export const rgbToHex = val => {
    let r, g, b,
        regRgba = /rgba?\((\d{1,3}),(\d{1,3}),(\d{1,3})(,([.\d]+))?\)/,
        rsa = val.replace(/\s+/g, '').match(regRgba)
    if (rsa) {
        r = parseInt(rsa[1]).toString(16)
        r = r.length == 1 ? '0' + r : r
        g = (+rsa[2]).toString(16)
        g = g.length == 1 ? '0' + g : g
        b = (+rsa[3]).toString(16)
        b = b.length == 1 ? '0' + b : b
        return r + g + b
    } else {
        return val
    }
}
export const hexToRgb = (val, a) => {
    // 16进制颜色值的正则
    let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
    // 把颜色值变成小写
    let color = val.toLowerCase()
    let result = ''
    if (reg.test(color)) {
        // 如果只有三位的值，需变成六位，如：#fff => #ffffff
        if (color.length === 4) {
            let colorNew = '#'
            for (let i = 1; i < 4; i += 1) {
                colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1))
            }
            color = colorNew
        }
        // 处理六位的颜色值，转为RGB
        let colorChange = []
        for (let i = 1; i < 7; i += 2) {
            colorChange.push(parseInt('0x' + color.slice(i, i + 2)))
        }
        result = 'rgba(' + colorChange.join(',') + ',' + a + ')'
        return result
    } else {
        return val
    }
}
/* -----------------树状结构--------------------*/
// 递归查找没有子节点对象，返回数组
export const dataNotChildren = data => {
    let notChild = []
    const notChildFunc = data => {
        data.forEach(element => {
            if (element['children'] === undefined || element['children'].length === 0) {
                notChild.push(element)
            } else {
                notChildFunc(element['children'])
            }
        })
    }
    notChildFunc(data)
    return notChild
}
/**
 * 防抖
 * name: debounce
 * @param {Function} fn
 * @param {Number} wait
 * @param {Boolean} immediate
 * @return {Function}
 */
export const debounce = (fn, wait, immediate) => {
    let timeout;
    let result;
    let debounced = function() {
        let context = this;
        let args = arguments;
        if( timeout ) {
            clearTimeout(timeout);
        }
        if( immediate ) {
            let callNow = !timeout;
            timeout = setTimeout(function() {
                timeout = null;
            }, wait);
            if( callNow ) {
                result = fn.apply(context, args);
            }
        } else {
            timeout = setTimeout(function() {
                fn.apply(context, args);
            }, wait);
        }
        return result;
    };
    debounced.cancel = function() {
        clearTimeout(timeout);
        timeout = null;
    };
    return debounced;
};

/**
 * 节流
 * name: throttle
 * @param {Function} fn
 * @param {Number} wait
 * @param {Object} options
 * @return {Function}
 */
export const throttle = (fn, wait, options) => {
    let time, context, args, result;
    let previous = 0;
    if (!options) options = {};
    
    let later = function() {
        previous = options.leading === false ? 0 : new Date().getTime();
        time = null;
        fn.apply(context, args);
        if (!time) context = args = null;
    };
    
    let throttled = function() {
        let now = new Date().getTime();
        if (!previous && options.leading === false) previous = now;
        let remaining = wait - (now - previous);
        context = this;
        args = arguments;
        if (remaining <= 0 || remaining > wait) {
            if (time) {
                clearTimeout(time);
                time = null;
            }
            previous = now;
            result = fn.apply(context, args);
            if (!time) context = args = null;
        } else if (!time && options.trailing !== false) {
            time = setTimeout(later, remaining);
        }
        return result;
    };
    throttled.cancel = function() {
        clearTimeout(time);
        time = null;
        previous = 0;
    }
    return throttled;
};

/**
 * 计时器
 * name: theTimer
 * @param {Function} fn
 * @param {Number} wait
 * @return {Function}
 */

export const theTimer = (fn, wait) => {
    let time, args;
    let theTimered = function() {
        args = arguments;
        fn.apply(this, args);
        time = setInterval(fn,wait);
    }
    theTimered.cancel = function() {
        clearInterval(time)
        time = null;
    }
    return theTimered;
}
